package com.artisan.springuitls.demos;

import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * DigestUtils 工具类演示
 * 功能：加密工具精简版
 * 优势：提供 MD5/SHA-256 基础功能，无需引入 Commons Codec
 * 
 * ⚠️ 生产警告：MD5 已不安全！密码加密必须用 BCryptPasswordEncoder
 * ⚠️ 仅用于：校验文件完整性等非敏感场景
 */
@Component
public class DigestUtilsDemo {

    /**
     * 场景：演示 MD5 加密（仅示例，生产勿用于密码）
     */
    public String encodePassword(String rawPassword) {
        System.out.println("\n========== DigestUtils Demo ==========");
        
        // ✅ 一行 MD5：返回 32 位小写 hex
        String md5 = DigestUtils.md5DigestAsHex(rawPassword.getBytes(StandardCharsets.UTF_8));
        System.out.println("MD5('" + rawPassword + "'): " + md5);
        return md5;
    }

    /**
     * 演示各种摘要算法
     */
    public void demonstrateDigestAlgorithms() {
        System.out.println("\n--- 各种摘要算法 ---");
        
        String text = "Hello Spring Boot!";
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        
        // 1. MD5 摘要（字节数组）
        byte[] md5Bytes = DigestUtils.md5Digest(bytes);
        System.out.println("✓ MD5 字节长度: " + md5Bytes.length); // 16 bytes
        
        // 2. MD5 摘要（十六进制字符串）
        String md5Hex = DigestUtils.md5DigestAsHex(bytes);
        System.out.println("✓ MD5 Hex: " + md5Hex); // 32 字符
        
        // 3. SHA-1 摘要（已不推荐）
        // byte[] sha1Bytes = DigestUtils.sha1Digest(bytes);
        // System.out.println("✓ SHA-1 字节长度: " + sha1Bytes.length); // 20 bytes
        
        // 4. 注意：Spring 5.x 可能只提供 MD5
        System.out.println("✓ 注意：Spring DigestUtils 主要提供 MD5");
        System.out.println("✓ 建议：使用 Java MessageDigest 获取 SHA-256");
        
        System.out.println();
    }

    /**
     * 演示流式摘要计算
     */
    public void demonstrateStreamDigest() throws IOException {
        System.out.println("\n--- 流式摘要计算 ---");
        
        String content = "这是一段需要计算摘要的文本内容";
        InputStream inputStream = new ByteArrayInputStream(
            content.getBytes(StandardCharsets.UTF_8));
        
        // ✅ 从流计算 MD5
        String md5FromStream = DigestUtils.md5DigestAsHex(inputStream);
        System.out.println("✓ 流 MD5: " + md5FromStream);
        
        // 重新创建流（因为上面的流已读完）
        inputStream = new ByteArrayInputStream(
            content.getBytes(StandardCharsets.UTF_8));
        
        System.out.println("✓ 建议使用 Java MessageDigest 处理 SHA 算法");
        
        System.out.println();
    }

    /**
     * 实际应用场景：文件完整性校验
     */
    public void demonstrateFileIntegrityCheck() {
        System.out.println("\n--- 文件完整性校验场景 ---");
        
        // 模拟下载文件
        String downloadedContent = "文件内容数据";
        String expectedMd5 = "预期的MD5值";
        
        // 计算实际 MD5
        String actualMd5 = DigestUtils.md5DigestAsHex(
            downloadedContent.getBytes(StandardCharsets.UTF_8));
        
        System.out.println("✓ 实际 MD5: " + actualMd5);
        System.out.println("✓ 预期 MD5: " + expectedMd5);
        
        // 校验完整性
        boolean isValid = actualMd5.equals(expectedMd5);
        System.out.println("✓ 文件完整性: " + (isValid ? "通过" : "失败"));
        
        System.out.println();
    }

    /**
     * 对比常见密码的 MD5（演示用，勿用于生产）
     */
    public void demonstrateCommonPasswords() {
        System.out.println("\n--- 常见密码 MD5（仅演示） ---");
        
        String[] passwords = {"123456", "password", "admin123", "qwerty"};
        
        for (String pwd : passwords) {
            String md5 = DigestUtils.md5DigestAsHex(pwd.getBytes(StandardCharsets.UTF_8));
            System.out.println("✓ '" + pwd + "' => " + md5);
        }
        
        System.out.println();
        System.out.println("⚠️ 重要提醒：");
        System.out.println("   - MD5 已被证明不安全，存在碰撞攻击风险");
        System.out.println("   - 密码存储必须使用 BCrypt、SCrypt、Argon2 等算法");
        System.out.println("   - Spring Security 推荐：BCryptPasswordEncoder");
        System.out.println("==========================================\n");
    }

    /**
     * 推荐的密码加密方式
     */
    public void demonstrateBcryptAlternative() {
        System.out.println("\n--- 生产环境密码加密推荐 ---");
        System.out.println("❌ 不推荐：DigestUtils.md5DigestAsHex(password)");
        System.out.println("✅ 推荐方式：");
        System.out.println("   @Autowired");
        System.out.println("   private PasswordEncoder passwordEncoder;");
        System.out.println("   ");
        System.out.println("   // 加密");
        System.out.println("   String encoded = passwordEncoder.encode(rawPassword);");
        System.out.println("   ");
        System.out.println("   // 验证");
        System.out.println("   boolean matches = passwordEncoder.matches(rawPassword, encoded);");
        System.out.println("==========================================\n");
    }
}

